﻿#region LicenseInfo
/*
 * WoW Automation
 * Copyright 2008, 2009
 * Michael Sutton
 * 
 * This file is part of Wow Automation.
 * 
 * Wow Automation is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Wow Automation is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Wow Automation.  If not, see <http://www.gnu.org/licenses/>.
*/
#endregion
using System.Windows.Forms;
using DXI = Microsoft.DirectX.DirectInput;


namespace Automation
{
    public class KeyMonitorThread
    {

        DXI.Device keyboard;
        Form _parent;
        public void AcquireKeyboard(Form parent)
        {
            keyboard = new DXI.Device(DXI.SystemGuid.Keyboard);
            keyboard.SetDataFormat(DXI.DeviceDataFormat.Keyboard);
            keyboard.SetCooperativeLevel(parent, DXI.CooperativeLevelFlags.Background | DXI.CooperativeLevelFlags.NonExclusive);
            keyboard.Properties.BufferSize = 10;
            keyboard.Acquire();
            _parent = parent;
        }

        /// <summary>
        /// Lock covering stopping and stopped
        /// </summary>
        readonly object stopLock = new object();
        /// <summary>
        /// Whether or not the worker thread has been asked to stop
        /// </summary>
        bool stopping;
        /// <summary>
        /// Whether or not the worker thread has stopped
        /// </summary>
        bool stopped;


        /// <summary>
        /// Returns whether the worker thread has been asked to stop.
        /// This continues to return true even after the thread has stopped.
        /// </summary>
        public bool Stopping
        {
            get
            {
                lock (stopLock)
                {
                    return stopping;
                }
            }
        }

        /// <summary>
        /// Returns whether the worker thread has stopped.
        /// </summary>
        public bool Stopped
        {
            get
            {
                lock (stopLock)
                {
                    return stopped;
                }
            }
        }

        /// <summary>
        /// Tells the worker thread to stop, typically after completing its 
        /// current work item. (The thread is *not* guaranteed to have stopped
        /// by the time this method returns.)
        /// </summary>
        public void Stop()
        {
            lock (stopLock)
            {
                stopping = true;
            }
        }

        /// <summary>
        /// Called by the worker thread to indicate when it has stopped.
        /// </summary>
        void SetStopped()
        {
            lock (stopLock)
            {
                stopped = true;
            }
        }

        /// <summary>
        /// Main work loop of the class.
        /// </summary>
        public void Run()
        {
            try
            {
                //actHook = new gma.System.Windows.UserActivityHook(false, true); // crate an instance with global hooks
                //actHook.KeyUp += new KeyEventHandler(actHook_KeyUp);
                //actHook.Start(false,true);
          
                while (!Stopping)
                {
                    CommonVariables.Pause(250);
                    // Insert work here. Make sure it doesn't tight loop!
                    // (If work is arriving periodically, use a queue and Monitor.Wait,
                    // changing the Stop method to pulse the monitor as well as setting
                    // stopping.)

                    // Note that you may also wish to break out *within* the loop
                    // if work items can take a very long time but have points at which
                    // it makes sense to check whether or not you've been asked to stop.
                    // Do this with just:
                    if (Stopping)
                     {
                         return;
                     }

                    // The finally block will make sure that the stopped flag is set.
                    DXI.BufferedDataCollection dataCollection = keyboard.GetBufferedData();
                  
                    if (dataCollection != null)
                    {
                        //loop through the keys changed  
                        foreach (DXI.BufferedData data in dataCollection)
                        {
                            DXI.Key key = (DXI.Key)data.Offset;    //now we have the key    
                            if (key != DXI.Key.F5)
                            if (key == DXI.Key.F12)
                            {
                                _parent.Invoke(((MainApplicationForm)_parent).myDelegate());
                      
                               
                            }
                            //do something with it here  
                        }
                    }

                }
            }
            finally
            {
                SetStopped();
               // actHook.Stop();
            }
        }
    }
}
